public class MultinomialClassifier extends BaseClassifier {
  public MultinomialClassifier() { super(); }
  
  public MultinomialClassifier(MessageIterator mi) {
    super(mi);
  }
  
  /**
   * Adjusts count
   * @override
   */
  void adjustCount(MessageFeatures mf, String term) {
    termCount.incrementCount(term, mf.newsgroupNumber, mf.body.getCount(term));
  }
  
  /**
   * Calculates the multinomial conditional probabilities P(t|c) (see formula 13.6).
   * One thing this doesn't do is handle terms never seen before in test set
   * @override
   */
  void calculateConditionalProbabilities() {
    for(String term : termCount.keySet()) {
      double totalTermOccurrencesInCorpus = termCount.getCounter(term).totalCount();
      for(int newsgroup = 0; newsgroup < newsgroupCount.size(); newsgroup++) {
        double numerator = termCount.getCount(term, newsgroup) + 1;
        double denominator = totalTermOccurrencesInCorpus + termCount.keySet().size();
        conditionalProbabilities.setCount(term, newsgroup, numerator / denominator);
      }
    }
  }
  
  double getScore(MessageFeatures message, int newsgroup) {
    //double score = Math.log(newsgroupPrior.getCount(newsgroup));
    double score = 0;
    for(String term : message.body.keySet()) {
      if(conditionalProbabilities.getCount(term, newsgroup) == 0) {
        //For terms never seen before
        score += Math.log(1 / (double) termCount.keySet().size());
      } else {
        score += Math.log(conditionalProbabilities.getCount(term, newsgroup));
      }
    }
    return score;
  }
}
